#include "Precompiled.h"
#include "SkeletonStore.h"

namespace Sandbox
{
	typedef std::vector<Eifersucht::SceneChildPtr> SceneChildren;
	TinyTypeDecl(SceneChildren);
};

void Sandbox::SkeletonStore::Import( _In_ Eifersucht::ScenePtr scene )
{
	return Import(scene->GetRootChild());
}

namespace Sandbox
{
	static void _gs_Extract_dummies( 
		_In_ Eifersucht::SceneChildPtr lclRoot,
		_In_ Eifersucht::XformBase::PropertyChannelPairU64 const &pair,
		_Inout_ SceneChildrenPtr dummies,
		_Inout_ Sandbox::SkeletonStore::int32x3 &maxtkeys, 
		_Inout_ Sandbox::SkeletonStore::int32x3 &maxrkeys, 
		_Inout_ Sandbox::SkeletonStore::int32x3 &maxskeys
		)
	{
		using namespace Eifersucht;

		auto numChildren = lclRoot->GetChildrenCount();
		for (decltype(numChildren) childIndex = 0;  childIndex < numChildren; childIndex++)
		{
			auto child = (*lclRoot->GetChildAt(childIndex));
			if (child->GetChildContextType() == SceneChildContext::Bone)
			{
				dummies->push_back(child);

				if (child->LclTranslationCache != nullptr)
				{
					auto channelPx = child->LclTranslationCache->Get<XformPropertyChannel::XChannel>();
					auto channelPy = child->LclTranslationCache->Get<XformPropertyChannel::YChannel>();
					auto channelPz = child->LclTranslationCache->Get<XformPropertyChannel::ZChannel>();

					auto const numPx = channelPx != nullptr ? channelPx->Curves[pair]->Knots.size() : 0;
					auto const numPy = channelPy != nullptr ? channelPy->Curves[pair]->Knots.size() : 0;
					auto const numPz = channelPz != nullptr ? channelPz->Curves[pair]->Knots.size() : 0;

					if (maxtkeys.x < numPx) maxtkeys.x = numPx; 
					if (maxtkeys.y < numPy) maxtkeys.y = numPy; 
					if (maxtkeys.z < numPz) maxtkeys.z = numPz;
				}

				if (child->LclRotationCache != nullptr)
				{
					auto channelRx = child->LclRotationCache->Get<XformPropertyChannel::XChannel>();
					auto channelRy = child->LclRotationCache->Get<XformPropertyChannel::YChannel>();
					auto channelRz = child->LclRotationCache->Get<XformPropertyChannel::ZChannel>();

					auto const numRx = channelRx != nullptr ? channelRx->Curves[pair]->Knots.size() : 0;
					auto const numRy = channelRy != nullptr ? channelRy->Curves[pair]->Knots.size() : 0;
					auto const numRz = channelRz != nullptr ? channelRz->Curves[pair]->Knots.size() : 0;

					if (maxrkeys.x < numRx) maxrkeys.x = numRx; 
					if (maxrkeys.y < numRy) maxrkeys.y = numRy; 
					if (maxrkeys.z < numRz) maxrkeys.z = numRz;
				}

				if (child->LclScaleCache != nullptr)
				{
					auto channelSx = child->LclScaleCache->Get<XformPropertyChannel::XChannel>();
					auto channelSy = child->LclScaleCache->Get<XformPropertyChannel::YChannel>();
					auto channelSz = child->LclScaleCache->Get<XformPropertyChannel::ZChannel>();

					auto const numSx = channelSx != nullptr ? channelSx->Curves[pair]->Knots.size() : 0;
					auto const numSy = channelSy != nullptr ? channelSy->Curves[pair]->Knots.size() : 0;
					auto const numSz = channelSz != nullptr ? channelSz->Curves[pair]->Knots.size() : 0;

					if (maxskeys.x < numSx) maxskeys.x = numSx; 
					if (maxskeys.y < numSy) maxskeys.y = numSy; 
					if (maxskeys.z < numSz) maxskeys.z = numSz;
				}

				_gs_Extract_dummies(child, pair, dummies, maxtkeys, maxrkeys, maxskeys);
			}
		}
	}

	void _Process_property( 
		_In_ Eifersucht::XformBase::PropertyChannelPairU64 const &pair,
		_Inout_ Eifersucht::SceneChild *dummy,
		_Inout_ Reign::Vector4 *vectorsXChannel,
		_Inout_ Reign::Vector4 *vectorsYChannel,
		_Inout_ Reign::Vector4 *vectorsZChannel,
		_Inout_ Reign::Vector2 *jointsXChannel,
		_Inout_ Reign::Vector2 *jointsYChannel,
		_Inout_ Reign::Vector2 *jointsZChannel,
		_Inout_ Eifersucht::XformBase::PropertyCache *dummyXformProperty,
		_In_ Sandbox::SkeletonStore::int32x3 &numPropertyKeys,
		_In_ int32 dummyId,
		_In_ Sandbox::SkeletonStore::int32x3 const keysCount,
		_In_ Reign::Vector3 defaultValue = Reign::Vector3(0.0f)
		)
	{
		using namespace Eifersucht;

		static auto calcIndexVv = [] (int32 i, int32 j, int32 dummyId, int32 im, int32 jm) { return im * jm * dummyId + im * j + i; };
		static auto calcIndexSs = [] (int32 i, int32 j, int32 im) { return im * j + i; };

		//
		static Eifersucht::_Intme_dbg_msg s_szmsg = {0};
		//

		if (dummyXformProperty != nullptr)
		{ // translation

			auto xChannelCache = dummyXformProperty->Get<XformPropertyChannel::XChannel>()->Curves[pair];
			numPropertyKeys.x = xChannelCache->Knots.size();

			for (int keyIndex = 0; keyIndex < numPropertyKeys.x; keyIndex++)
			{
				auto const xChannelIndex = calcIndexSs(keyIndex, dummyId, keysCount.x);
				vectorsXChannel[xChannelIndex].x = xChannelCache->Knots[keyIndex]->Meets.x;
				vectorsXChannel[xChannelIndex].y = xChannelCache->Knots[keyIndex]->Meets.y;
				vectorsXChannel[xChannelIndex].z = xChannelCache->Knots[keyIndex]->Leaves.x;
				vectorsXChannel[xChannelIndex].w = xChannelCache->Knots[keyIndex]->Leaves.y;
				jointsXChannel[xChannelIndex].y = xChannelCache->Knots[keyIndex]->Point.y;
				jointsXChannel[xChannelIndex].x = xChannelCache->Knots[keyIndex]->Point.x;

				//
				/*_Rgn_sprintf(s_szmsg, "\t\t> X [%d] p<%f; %f> l<%f; %f> m<%f; %f> ", 
					xChannelIndex, jointsXChannel[xChannelIndex].x, jointsXChannel[xChannelIndex].y,
					vectorsXChannel[xChannelIndex].z, vectorsXChannel[xChannelIndex].w,
					vectorsXChannel[xChannelIndex].x, vectorsXChannel[xChannelIndex].y
					); PrintToDebugWindowOnly8(s_szmsg);*/
				//
			}

			auto yChannelCache = dummyXformProperty->Get<XformPropertyChannel::YChannel>()->Curves[pair];
			numPropertyKeys.y = yChannelCache->Knots.size();

			for (int keyIndex = 0; keyIndex < numPropertyKeys.y; keyIndex++)
			{
				auto const yChannelIndex = calcIndexSs(keyIndex, dummyId, keysCount.y);
				vectorsYChannel[yChannelIndex].x = yChannelCache->Knots[keyIndex]->Meets.x ;
				vectorsYChannel[yChannelIndex].y = yChannelCache->Knots[keyIndex]->Meets.y ;
				vectorsYChannel[yChannelIndex].z = yChannelCache->Knots[keyIndex]->Leaves.x ;
				vectorsYChannel[yChannelIndex].w = yChannelCache->Knots[keyIndex]->Leaves.y ;
				jointsYChannel[yChannelIndex].y = yChannelCache->Knots[keyIndex]->Point.y;
				jointsYChannel[yChannelIndex].x = yChannelCache->Knots[keyIndex]->Point.x;

				//
				/*_Rgn_sprintf(s_szmsg, "\t\t> Y [%d] p<%f; %f> l<%f; %f> m<%f; %f> ", yChannelIndex,
					jointsYChannel[yChannelIndex].x, jointsYChannel[yChannelIndex].y,
					vectorsYChannel[yChannelIndex].z, vectorsYChannel[yChannelIndex].w,
					vectorsYChannel[yChannelIndex].x, vectorsYChannel[yChannelIndex].y
					); PrintToDebugWindowOnly8(s_szmsg);*/
				//
			}

			auto zChannelCache = dummyXformProperty->Get<XformPropertyChannel::ZChannel>()->Curves[pair];
			numPropertyKeys.z = zChannelCache->Knots.size();

			for (int keyIndex = 0; keyIndex < numPropertyKeys.z; keyIndex++)
			{
				auto const zChannelIndex = calcIndexSs(keyIndex, dummyId, keysCount.z);
				vectorsZChannel[zChannelIndex].x = zChannelCache->Knots[keyIndex]->Meets.x ;
				vectorsZChannel[zChannelIndex].y = zChannelCache->Knots[keyIndex]->Meets.y ;
				vectorsZChannel[zChannelIndex].z = zChannelCache->Knots[keyIndex]->Leaves.x ;
				vectorsZChannel[zChannelIndex].w = zChannelCache->Knots[keyIndex]->Leaves.y ;
				jointsZChannel[zChannelIndex].y = zChannelCache->Knots[keyIndex]->Point.y;
				jointsZChannel[zChannelIndex].x = zChannelCache->Knots[keyIndex]->Point.x;

				//
				/*_Rgn_sprintf(s_szmsg, "\t\t> Z [%d] p<%f; %f> l<%f; %f> m<%f; %f> ", zChannelIndex,
					jointsZChannel[zChannelIndex].x, jointsZChannel[zChannelIndex].y,
					vectorsZChannel[zChannelIndex].z, vectorsZChannel[zChannelIndex].w,
					vectorsZChannel[zChannelIndex].x, vectorsZChannel[zChannelIndex].y
					);  PrintToDebugWindowOnly8(s_szmsg);*/
				//
			}
		}
		else
		{
			auto const xChannelIndex = calcIndexSs(0, dummyId, keysCount.x);
			auto const yChannelIndex = calcIndexSs(0, dummyId, keysCount.y);
			auto const zChannelIndex = calcIndexSs(0, dummyId, keysCount.z);
			jointsXChannel[xChannelIndex].y = defaultValue.x; //0.0f; //dummy->LclTranslation.x; 
			jointsYChannel[yChannelIndex].y = defaultValue.y; //0.0f; //dummy->LclTranslation.y;
			jointsZChannel[zChannelIndex].y = defaultValue.z; //0.0f; //dummy->LclTranslation.z;

			//
			//_Rgn_sprintf(s_szmsg, "\t\t> X [%d] = %f ", xChannelIndex, jointsXChannel[xChannelIndex].y); PrintToDebugWindowOnly8(s_szmsg);
			//_Rgn_sprintf(s_szmsg, "\t\t> Y [%d] = %f ", yChannelIndex, jointsYChannel[yChannelIndex].y); PrintToDebugWindowOnly8(s_szmsg);
			//_Rgn_sprintf(s_szmsg, "\t\t> Z [%d] = %f ", zChannelIndex, jointsZChannel[zChannelIndex].y); PrintToDebugWindowOnly8(s_szmsg);
			//
		}
	}
};


void Sandbox::SkeletonStore::Import( Eifersucht::SceneChildPtr rootChild )
{
	using namespace Eifersucht;
	static XformBase::PropertyChannelPairU64 const pair(0, 0);

	//
	static Eifersucht::_Intme_dbg_msg s_szmsg = {0};
	//

	Sandbox::SkeletonStore::int32x3 keysCount[3];
	Reign::Standard::ZeroValueArray(keysCount, ARRAYSIZE(keysCount));

	SceneChildren dummies;

	// Get all the bones from the scene.
	// Get some statistic info to alloc resources.
	_gs_Extract_dummies(
		rootChild, pair, &dummies, 
		keysCount[0], 
		keysCount[1], 
		keysCount[2] 
		);

	for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++)
		if (keysCount[i][j] < 1) keysCount[i][j] = 1;

	auto dummiesCount = dummies.size();

	auto sstLength = keysCount[0] * dummiesCount;// auto vvtLength = sstLength * 3;
	auto ssrLength = keysCount[1] * dummiesCount;// auto vvrLength = ssrLength * 3;
	auto sssLength = keysCount[2] * dummiesCount;// auto vvsLength = sssLength * 3;

	// Translation: 

	auto *translationVectorsXChannel = new Reign::Vector4[sstLength.x]; Reign::Standard::ZeroValueArray(translationVectorsXChannel, sstLength.x);
	auto *translationVectorsYChannel = new Reign::Vector4[sstLength.y]; Reign::Standard::ZeroValueArray(translationVectorsYChannel, sstLength.y);
	auto *translationVectorsZChannel = new Reign::Vector4[sstLength.z]; Reign::Standard::ZeroValueArray(translationVectorsZChannel, sstLength.z);
	auto *translationJointsXChannel = new Reign::Vector2[sstLength.x]; Reign::Standard::ZeroValueArray(translationJointsXChannel, sstLength.x);
	auto *translationJointsYChannel = new Reign::Vector2[sstLength.y]; Reign::Standard::ZeroValueArray(translationJointsYChannel, sstLength.y);
	auto *translationJointsZChannel = new Reign::Vector2[sstLength.z]; Reign::Standard::ZeroValueArray(translationJointsZChannel, sstLength.z);

	// Rotation: 

	auto *rotationVectorsXChannel = new Reign::Vector4[ssrLength.x]; Reign::Standard::ZeroValueArray(rotationVectorsXChannel, ssrLength.x);
	auto *rotationVectorsYChannel = new Reign::Vector4[ssrLength.y]; Reign::Standard::ZeroValueArray(rotationVectorsYChannel, ssrLength.y);
	auto *rotationVectorsZChannel = new Reign::Vector4[ssrLength.z]; Reign::Standard::ZeroValueArray(rotationVectorsZChannel, ssrLength.z);
	auto *rotationJointsXChannel = new Reign::Vector2[ssrLength.x]; Reign::Standard::ZeroValueArray(rotationJointsXChannel, ssrLength.x);
	auto *rotationJointsYChannel = new Reign::Vector2[ssrLength.y]; Reign::Standard::ZeroValueArray(rotationJointsYChannel, ssrLength.y);
	auto *rotationJointsZChannel = new Reign::Vector2[ssrLength.z]; Reign::Standard::ZeroValueArray(rotationJointsZChannel, ssrLength.z);

	// Scale: 

	auto *scaleVectorsXChannel = new Reign::Vector4[sssLength.x]; Reign::Standard::ZeroValueArray(scaleVectorsXChannel, sssLength.x);
	auto *scaleVectorsYChannel = new Reign::Vector4[sssLength.y]; Reign::Standard::ZeroValueArray(scaleVectorsYChannel, sssLength.y);
	auto *scaleVectorsZChannel = new Reign::Vector4[sssLength.z]; Reign::Standard::ZeroValueArray(scaleVectorsZChannel, sssLength.z);
	auto *scaleJointsXChannel = new Reign::Vector2[sssLength.x]; Reign::Standard::ZeroValueArray(scaleJointsXChannel, sssLength.x);
	auto *scaleJointsYChannel = new Reign::Vector2[sssLength.y]; Reign::Standard::ZeroValueArray(scaleJointsYChannel, sssLength.y);
	auto *scaleJointsZChannel = new Reign::Vector2[sssLength.z]; Reign::Standard::ZeroValueArray(scaleJointsZChannel, sssLength.z);

	// Info:

	auto *dummiesInfo = new DummyInfo[dummiesCount]; Reign::Standard::ZeroValueArray(dummiesInfo, dummiesCount);
	auto *dummiesPropsDims = new DummyPropertiesDims[dummiesCount]; Reign::Standard::ZeroValueArray(dummiesPropsDims, dummiesCount);

	for (decltype(dummiesCount) dummyIndex = 0; dummyIndex < dummiesCount; dummyIndex++)
	{
		auto dummy = dummies[dummyIndex];
		//dummiesInfo[dummyIndex].Id = dummy->UniqueId();
		//dummiesInfo[dummyIndex].ParentsCount = (0);

		//
		_Rgn_sprintf(s_szmsg, "\tIndex=%d => Id=%d Name=%s", dummyIndex, dummy->UniqueId(), dummy->GetName().c_str());
		PrintToDebugWindowOnly8(s_szmsg);
		//

		//PrintToDebugWindowOnly8("Translation:");
		_Process_property(
			pair, 
			dummy, 
			translationVectorsXChannel,
			translationVectorsYChannel,
			translationVectorsZChannel,
			translationJointsXChannel,
			translationJointsYChannel,
			translationJointsZChannel,
			dummy->LclTranslationCache,
			dummiesPropsDims[dummyIndex].TranslationKeysCount,
			dummyIndex, 
			keysCount[0],
			dummy->LclTranslation
			);

		//PrintToDebugWindowOnly8("Rotation:");
		_Process_property(
			pair, 
			dummy, 
			rotationVectorsXChannel,
			rotationVectorsYChannel,
			rotationVectorsZChannel,
			rotationJointsXChannel,
			rotationJointsYChannel,
			rotationJointsZChannel,
			dummy->LclRotationCache,
			dummiesPropsDims[dummyIndex].RotationKeysCount,
			dummyIndex, keysCount[1],
			dummy->LclRotation
			);

		//PrintToDebugWindowOnly8("Scale:");
		_Process_property(
			pair, 
			dummy, 
			scaleVectorsXChannel,
			scaleVectorsYChannel,
			scaleVectorsZChannel,
			scaleJointsXChannel,
			scaleJointsYChannel,
			scaleJointsZChannel,
			dummy->LclScaleCache,
			dummiesPropsDims[dummyIndex].ScaleKeysCount,
			dummyIndex, keysCount[2],
			dummy->LclScale
			);

	} // dummies
	PrintToDebugWindowOnly8("Hierarchy:");
	for (decltype(dummiesCount) i = 0; i < dummiesCount; i++) // dummies
	{
		auto dummy = dummies[i];
		auto parentChild = dummy->GetParentChild();
		auto parentId = parentChild->UniqueId();

		if (!parentChild->IsRootChild()) for (decltype(dummiesCount) j = 0; j < dummiesCount; j++) 
		{
			if (i != j && parentChild == dummies[j])
			{
				dummiesInfo[i].ParentIndex = j; break;
			} else continue;
		} else dummiesInfo[i].ParentIndex = -1;
		
		//
		_Rgn_sprintf(s_szmsg, "\tIndex=%d => ParentId=%d ParentIndex=%d", i, parentId, dummiesInfo[i].ParentIndex);
		PrintToDebugWindowOnly8(s_szmsg);
		//

	} // dummies
	{ // Shaders & buffers
		Sehnsucht::IO::BasicLoader loader(m_d3dDevice); 
		auto loaderPtr = &loader;

		loaderPtr->LoadShader( L"EvaluateLocalXform.cso", 
			m_evaluateLclWorlds.GetAddressOf()
			);

		loaderPtr->LoadShader( L"EvaluateGlobalXform.cso", 
			m_evaluateGlbWorlds.GetAddressOf()
			);

		loaderPtr->CreateStructuredBuffer<DummyInfo>( 
			dummiesCount, 
			m_bonesInfos.Rsrc.GetAddressOf(), 
			m_bonesInfos.Read.GetAddressOf(), 
			nullptr, dummiesInfo
			);
		loaderPtr->CreateStructuredBuffer<DummyPropertiesDims>( 
			dummiesCount, 
			m_bonesPropsDims.Rsrc.GetAddressOf(), 
			m_bonesPropsDims.Read.GetAddressOf(), 
			nullptr, dummiesPropsDims
			);

		loaderPtr->CreateStructuredBuffer<DummyWorld>( 
			dummiesCount, 
			m_bonesLclWorlds.Rsrc.GetAddressOf(), 
			m_bonesLclWorlds.Read.GetAddressOf(), 
			m_bonesLclWorlds.Write.GetAddressOf(), 
			nullptr
			);
		loaderPtr->CreateStructuredBuffer<DummyWorld>( 
			dummiesCount, 
			m_bonesGlbWorlds.Rsrc.GetAddressOf(), 
			m_bonesGlbWorlds.Read.GetAddressOf(), 
			m_bonesGlbWorlds.Write.GetAddressOf(), 
			nullptr
			);

		_Delete_pointer_array(dummiesPropsDims);
		_Delete_pointer_array(dummiesInfo);

	} // Shaders & buffers
	{ // Textures

		CD3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceDesc; Reign::Standard::ZeroValue(&shaderResourceDesc); 
		D3D11_SUBRESOURCE_DATA rsrcData[3]; Reign::Standard::ZeroValueArray(rsrcData, ARRAYSIZE(rsrcData));
		CD3D11_TEXTURE2D_DESC textureDesc; Reign::Standard::ZeroValue(&textureDesc);

		textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // | D3D11_BIND_UNORDERED_ACCESS;
		shaderResourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
		textureDesc.Usage = D3D11_USAGE_DEFAULT;

		textureDesc.ArraySize = ARRAYSIZE(rsrcData);
		textureDesc.Height = dummiesCount;
		textureDesc.MipLevels = 1;
		
		shaderResourceDesc.Texture2DArray.ArraySize = textureDesc.ArraySize;
		shaderResourceDesc.Texture2DArray.MipLevels = textureDesc.MipLevels;
		shaderResourceDesc.Texture2DArray.MostDetailedMip = 0;
		shaderResourceDesc.Texture2DArray.FirstArraySlice = 0;
		textureDesc.SampleDesc.Quality = 0;
		textureDesc.SampleDesc.Count = 1;

		Reign::Vector2 *translationJoints[3] = { translationJointsXChannel, translationJointsYChannel, translationJointsZChannel };
		Reign::Vector2 *rotationJoints[3] = { rotationJointsXChannel, rotationJointsYChannel, rotationJointsZChannel };
		Reign::Vector2 *scaleJoints[3] = { scaleJointsXChannel, scaleJointsYChannel, scaleJointsZChannel };
		Reign::Vector2 **joints[3] = { translationJoints, rotationJoints, scaleJoints };

		Reign::Vector4 *translationVectors[3] = { translationVectorsXChannel, translationVectorsYChannel, translationVectorsZChannel };
		Reign::Vector4 *rotationVectors[3] = { rotationVectorsXChannel, rotationVectorsYChannel, rotationVectorsZChannel };
		Reign::Vector4 *scaleVectors[3] = { scaleVectorsXChannel, scaleVectorsYChannel, scaleVectorsZChannel };
		Reign::Vector4 **vectors[3] = { translationVectors, rotationVectors, scaleVectors };

		for (int32 i = 0; i < 3; i++)
		{
			textureDesc.Width = keysCount[i].Max();

			textureDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R32G32_FLOAT;
			shaderResourceDesc.Format = textureDesc.Format;

			for (int j = 0; j < 3; j++)
			{
				rsrcData[j].SysMemPitch = textureDesc.Width * sizeof Reign::Vector2;
				rsrcData[j].SysMemSlicePitch = rsrcData[j].SysMemPitch * textureDesc.Height;
				rsrcData[j].pSysMem = joints[i][j];
			}

			m_d3dDevice->CreateTexture2D(&textureDesc, rsrcData, m_dummiesJoints[i].Rsrc.GetAddressOf());
			m_d3dDevice->CreateShaderResourceView(m_dummiesJoints[i].Rsrc.Get(), &shaderResourceDesc, m_dummiesJoints[i].Read.GetAddressOf());

			textureDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT;
			shaderResourceDesc.Format = textureDesc.Format;

			for (int j = 0; j < 3; j++)
			{
				rsrcData[j].SysMemPitch = textureDesc.Width * sizeof Reign::Vector4;
				rsrcData[j].SysMemSlicePitch = rsrcData[j].SysMemPitch * textureDesc.Height;
				rsrcData[j].pSysMem = vectors[i][j];
			}

			m_d3dDevice->CreateTexture2D(&textureDesc, rsrcData, m_dummiesVectors[i].Rsrc.GetAddressOf());
			m_d3dDevice->CreateShaderResourceView(m_dummiesVectors[i].Rsrc.Get(), &shaderResourceDesc, m_dummiesVectors[i].Read.GetAddressOf());

		}

		textureDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT;
		shaderResourceDesc.Format = textureDesc.Format;

		for (int32 i = 0; i < 3; i++) for (int32 j = 0; j < 3; j++)
		{
			_Delete_pointer_array(vectors[i][j]);
			_Delete_pointer_array(joints[i][j]);
		}

	} // Textures

	ID3D11ShaderResourceView *srvs[] = 
	{
		m_dummiesVectors[0].Read.Get(), m_dummiesVectors[1].Read.Get(), m_dummiesVectors[2].Read.Get(),
		m_dummiesJoints[0].Read.Get(), m_dummiesJoints[1].Read.Get(), m_dummiesJoints[2].Read.Get()
	};

	uint32 initialCounts[1] = { 0 };
	uint32 uavStartSlot = 0, 
		srvStartSlot = 0;

	m_d3dContext->CSSetShader(m_evaluateLclWorlds.Get(), nullptr, 0u);
	m_d3dContext->CSSetShaderResources(0, 1, m_bonesInfos.Read.GetAddressOf());
	m_d3dContext->CSSetUnorderedAccessViews(0, 1, m_bonesLclWorlds.Write.GetAddressOf(), initialCounts);
	m_d3dContext->CSSetShaderResources(1, 1, m_bonesPropsDims.Read.GetAddressOf());
	m_d3dContext->CSSetShaderResources(2, ARRAYSIZE(srvs), srvs);
	m_d3dContext->Dispatch(dummiesCount, 1, 1);
	
	m_d3dContext->CSSetShader(m_evaluateGlbWorlds.Get(), nullptr, 0u);
	m_d3dContext->CSSetShaderResources(0, 1, m_bonesInfos.Read.GetAddressOf());
	m_d3dContext->CSSetUnorderedAccessViews(0, 1, m_bonesGlbWorlds.Write.GetAddressOf(), initialCounts);
	m_d3dContext->CSSetShaderResources(1, 1, m_bonesLclWorlds.Read.GetAddressOf());
	m_d3dContext->Dispatch(dummiesCount, 1, 1);

}
